// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html

import Flower from "./flower";

const { ccclass, property } = cc._decorator;

@ccclass
export default class gameManager extends cc.Component {
  // LIFE-CYCLE CALLBACKS:
  @property(cc.Node)
  flowerPotNode: cc.Node = null;
  @property(cc.Node)
  pengWaiNode: cc.Node = null;
  pengWaiArr: cc.Node[] = [];
  onLoad() {
    cc.director.on("touchEnd", this.onTouchEnd, this);
  }

  start() {
    this.pengWaiNode.children.forEach((node) => {
      this.pengWaiArr.push(node);
    });
    this.initPeng();
    cc.log(
      'cc.find("Canvas/mainNode/flowerpot")',
      cc.find("Canvas/mainNode/flowerpot").children
    );
  }
  // 初始化花盆
  initPeng() {
    this.pengWaiArr.forEach((node) => {
      const nameArr = node.name.split("_");
      node["pengNo"] = Number(nameArr[1]);
      const floorNum = node.getChildByName("level")
        ? Number(node.getChildByName("level").getComponent(cc.Label).string) + 1
        : 1;
      node["floor"] = floorNum;
      // console.log("floorNum", node.name, floorNum);
      node["canHaveFlower"] = true;
      if (floorNum < 3) {
        node.opacity = 80;
        node["canHaveFlower"] = false;
      }
      if (floorNum == 1) {
        node.opacity = 0;
      }
    });
    // cc.log("初始化花盆", this.pengWaiArr);
  }
  // onTouchEnd(
  //   flowerNode: cc.Node,
  //   orginParent: cc.Node,
  //   orginWorldPos: cc.Vec2
  // ) {
  onTouchEnd(flowerNode: cc.Node) {
    // cc.log(flowerNode, "花");
    const floPos = flowerNode.getPosition();

    let minDis = 100;
    let endPos = null;

    const visiblePengArr = this.pengWaiArr.filter((node) => {
      return node.active && node["canHaveFlower"];
    });
    console.log("---------------visiblePengArr", visiblePengArr);
    let targetNode = null;
    for (let index = 0; index < visiblePengArr.length; index++) {
      const pengNode = visiblePengArr[index];
      console.log("-----------------------------pengNode", pengNode.children);
      const filterPengChildNode = pengNode.children.filter((node) => {
        return node.name != "level";
      });
      for (let index = 0; index < filterPengChildNode.length; index++) {
        const posNode = filterPengChildNode[index];

        let touchPosWorld = posNode.parent.convertToWorldSpaceAR(
          posNode.getPosition()
        );
        let localPos = flowerNode.parent.convertToNodeSpaceAR(touchPosWorld);

        let dis = cc.Vec2.distance(localPos, floPos);
        if (dis <= minDis) {
          minDis = dis;
          endPos = localPos;
          targetNode = posNode;
          //找到位置了
          // flowerNode.setPosition(localPos);
        } else {
        }
      }
    }
    // cc.log('targetNode["hasFlower"]', targetNode["hasFlower"]);
    let flowerCom = flowerNode.getComponent(Flower);
    let pengPosNode = flowerCom.pengPotNode;
    cc.log("targetNode", targetNode);
    if (targetNode === null || targetNode["hasFlower"]) {
      console.log("有花");
      // 返回原来的位置
      pengPosNode["hasFlower"] = true;
      pengPosNode["flowerNode"] = flowerNode;
      // let orginPos = orginParent.convertToNodeSpaceAR(orginWorldPos);
      let orginPosNodePos = pengPosNode.parent.convertToWorldSpaceAR(
        pengPosNode.getPosition()
      );
      const orginlocalPos =
        this.flowerPotNode.convertToNodeSpaceAR(orginPosNodePos);
      // flowerNode.setParent(orginParent);
      // flowerNode.setPosition(orginPos);
      flowerNode.setRotation(pengPosNode.rotation);
      flowerNode.setParent(this.flowerPotNode);
      flowerNode.setPosition(orginlocalPos);
    } else {
      console.log("没有花");
      // 移动到目标位置
      flowerNode.setPosition(endPos);
      const floworldPos = flowerNode.parent.convertToWorldSpaceAR(
        flowerNode.getPosition()
      );
      const localPos = this.flowerPotNode.convertToNodeSpaceAR(floworldPos);
      flowerNode.setPosition(localPos);
      flowerNode.setRotation(targetNode.rotation);
      flowerNode.setParent(this.flowerPotNode);
      // 更新花脚本里记录的posNode
      flowerCom.pengPotNode = targetNode;
      // console.log("orginParent", orginParent);
      // orginParent["hasFlower"] = false;
      pengPosNode["hasFlower"] = false;
      targetNode["hasFlower"] = true;
      pengPosNode["flowerNode"] = null;
      targetNode["flowerNode"] = flowerNode;
      this.checkEliminateNode(targetNode.parent);
      this.checkEmptyPeng(pengPosNode.parent);
    }
  }

  checkEliminateNode(node: cc.Node) {
    console.log("检查花盆");
    const pengziNode = node;
    const isAllHaveFlower = pengziNode.children
      .slice(0, 3)
      .every((posNode) => posNode["flowerNode"] !== null);
    cc.log("isAllHaveFlower", isAllHaveFlower);
    if (!isAllHaveFlower) return;

    const typeArr = pengziNode.children
      .slice(0, 3)
      .map((posNode) => posNode["flowerNode"]?.getComponent(Flower).type);
    cc.log("checkEliminateNode typeArr", typeArr);
    // 检查数组中的所有元素是否相同
    const isAllSame = typeArr.every((type) => type === typeArr[0]);
    cc.log("checkEliminateNode isAllSame", isAllSame);
    if (isAllSame) {
      cc.log("清除操作");
      for (
        let index = 0;
        index < pengziNode.children.slice(0, 3).length;
        index++
      ) {
        const posNode = pengziNode.children[index];
        posNode["hasFlower"] = false;
        posNode["flowerNode"].destroy();
        posNode["flowerNode"] = null;
      }
      this.showNextPeng(pengziNode);
      this.checkGameEnd();
    }
  }

  checkEmptyPeng(node: cc.Node) {
    const pengziNode = node;
    // 检查花盆中是否有空位
    const emptyPosNode = pengziNode.children.find(
      (posNode) => posNode["hasFlower"]
    );
    console.log("检查花盆中是否有空位---------", emptyPosNode);
    if (!emptyPosNode) {
      // for (
      //   let index = 0;
      //   index < pengziNode.children.slice(0, 3).length;
      //   index++
      // ) {
      //   const posNode = pengziNode.children[index];
      //   posNode["hasFlower"] = false;
      //   posNode["flowerNode"].destroy();
      //   posNode["flowerNode"] = null;
      // }
      this.showNextPeng(pengziNode);
    }
  }
  checkGameEnd() {
    const flowerpotNode = cc.find("Canvas/mainNode/flowerpot");
    const flowerNodeArr = flowerpotNode.children;
    if (flowerNodeArr.length == 0) {
      const gameOverNode = cc.find("Canvas/mainNode/gameEnd");
      gameOverNode.active = true;
    }
  }

  showNextPeng(pengziNode: cc.Node) {
    const flowerpotNode = cc.find("Canvas/mainNode/flowerpot");
    const pengNo = pengziNode["pengNo"];
    const floor = pengziNode["floor"];
    const nextPengNode = this.pengWaiArr.find((node) => {
      // cc.log(
      //   "showNextPeng node find",
      //   node["pengNo"],
      //   pengNo,
      //   node["floor"],
      //   floor
      // );
      return node["pengNo"] == pengNo && node["floor"] == floor - 1;
    });
    if (nextPengNode) {
      // 显示下一层的花盆
      nextPengNode["canHaveFlower"] = true;
      nextPengNode.opacity = 255;
      // 显示下一层的花朵
      const nextLevelFlowerNodeArr = flowerpotNode.children.filter(
        (node) =>
          node.getComponent(Flower).pengNo == pengNo &&
          node.getComponent(Flower).floor == floor - 1
      );
      cc.log(
        "nextLevelFlowerNodeArr nextLevelFlowerNodeArr",
        nextLevelFlowerNodeArr
      );
      nextLevelFlowerNodeArr.forEach((node) => {
        node.opacity = 255;
        node.getComponent(Flower).canTouch = true;
      });
      pengziNode.destroy();
      // 更新花盆数组
      // pengziNode.parent.children.forEach((node) => {
      //   this.pengWaiArr.push(node);
      // });

      // 如果是第三层才处理第一层
      if (floor == 3) {
        const lastPengNode = this.pengWaiArr.find((node) => {
          return node["pengNo"] == pengNo && node["floor"] == 1;
        });
        lastPengNode.opacity = 80;
        const lastLevelFlowerNodeArr = flowerpotNode.children.filter(
          (node) =>
            node.getComponent(Flower).pengNo == pengNo &&
            node.getComponent(Flower).floor == 1
        );
        lastLevelFlowerNodeArr.forEach((node) => {
          node.opacity = 80;
        });
      }
    }
  }

  onRefreshClick() {
    const flowerNodeArr = cc.find("Canvas/mainNode/flowerpot").children;
    let vecArr = [];
    let pengPotNodeArr = [];
    for (let index = 0; index < flowerNodeArr.length; index++) {
      const flowerNode = flowerNodeArr[index];
      pengPotNodeArr.push(flowerNode.getComponent(Flower).pengPotNode);
      vecArr.push({
        pengPotNode: flowerNode.getComponent(Flower).pengPotNode,

        pengNo: flowerNode.getComponent(Flower).pengNo,
        floor: flowerNode.getComponent(Flower).floor,

        canTouch: flowerNode.getComponent(Flower).canTouch,

        opacity: flowerNode.opacity,
        zIndex: flowerNode.zIndex,
        rotation: flowerNode.rotation,
        pos: flowerNode.position.clone(),
      });
    }
    // let copyVecArr = gameManager.copyDataHandler(vecArr);
    let shuffledArray = gameManager.fisherYatesShuffle(vecArr);
    cc.log(shuffledArray.map((data) => data.canTouch));

    // 先清除所有花盆位置节点的花朵引用
    pengPotNodeArr.forEach((posNode) => {
      posNode["hasFlower"] = false;
      posNode["flowerNode"] = null;
    });

    shuffledArray.forEach((data, index) => {
      const flowerNode = flowerNodeArr[index];
      flowerNode.setPosition(data.pos);
      flowerNode.rotation = data.rotation;
      flowerNode.opacity = data.opacity;
      flowerNode.zIndex = data.zIndex;
      flowerNode.getComponent(Flower).canTouch = data.floor == 3 ? true : false;
      flowerNode.getComponent(Flower).pengNo = data.pengNo;
      flowerNode.getComponent(Flower).floor = data.floor;
      flowerNode.getComponent(Flower).pengPotNode = data.pengPotNode;

      // 更新花盆位置节点的引用
      data.pengPotNode["hasFlower"] = true;
      data.pengPotNode["flowerNode"] = flowerNode;
    });
    cc.log(
      cc.find("Canvas/mainNode/flowerpot").children[0].getComponent(Flower)
    );
  }
  public static randomArr(arr: any[]): any[] {
    let outputArr: any[] = arr.slice();
    let i: number = outputArr.length;
    let temp: any;
    let indexA: number;
    let indexB: number;

    while (i) {
      indexA = i - 1;
      indexB = Math.floor(Math.random() * i);
      i--;

      if (indexA == indexB) continue;
      temp = outputArr[indexA];
      outputArr[indexA] = outputArr[indexB];
      outputArr[indexB] = temp;
    }

    return outputArr;
  }
  /**
   * Fisher-Yates Shuffle 随机置乱算法
   * @param array 目标数组
   */
  public static fisherYatesShuffle(array: any[]): any[] {
    let count = array.length;
    while (count) {
      let index = Math.floor(Math.random() * count--);
      let temp = array[count];
      array[count] = array[index];
      array[index] = temp;
    }
    return array;
  }
  /**
   * 深度复制，处理循环引用
   * @param obj 要复制的对象
   * @param hash 用于检测循环引用的 WeakMap
   */
  public static copyDataHandler(obj: any, hash = new WeakMap()): any {
    // 处理基本类型和null
    if (obj === null || typeof obj !== "object") {
      return obj;
    }

    // 检查是否已经复制过这个对象（处理循环引用）
    if (hash.has(obj)) {
      return hash.get(obj);
    }

    // 创建新对象
    let newObj;
    if (obj instanceof Array) {
      newObj = [];
    } else if (obj instanceof cc.Node || obj instanceof cc.Component) {
      // 对于 cc.Node 和 cc.Component 类型，不进行深拷贝，直接返回引用
      return obj;
    } else if (obj instanceof Object) {
      newObj = {};
    } else {
      return obj;
    }

    // 将新对象添加到 hash 中，以处理循环引用
    hash.set(obj, newObj);

    // 复制属性
    var keys = Object.keys(obj);
    for (var i: number = 0, len = keys.length; i < len; i++) {
      var key = keys[i];
      newObj[key] = this.copyDataHandler(obj[key], hash);
    }

    return newObj;
  }

  // checkEliminate() {
  //   const pengwaiNode = cc.find("Canvas/mainNode/pengWaiNode");
  //   console.log("mainNode根节点", cc.find("Canvas/mainNode"));
  //   for (let index = 0; index < pengwaiNode.children.length; index++) {
  //     const pengziNode = pengwaiNode.children[index];

  //     // 检查盆子中是不是插满花
  //     const isAllHaveFlower = pengziNode.children.every(
  //       (posNode) => posNode["flowerNode"] !== null
  //     );
  //     if (!isAllHaveFlower) continue;

  //     let typeArr = [];
  //     for (let index = 0; index < pengziNode.children.length; index++) {
  //       const posNode = pengziNode.children[index];

  //       const type = posNode["flowerNode"].getComponent(Flower).type;
  //       typeArr.push(type);
  //     }
  //     // 检查数组中的所有元素是否相同
  //     const isAllSame = typeArr.every((type) => type === typeArr[0]);
  //     if (isAllSame) {
  //       console.log("清除操作");
  //       // 执行相应的操作
  //       for (let index = 0; index < pengziNode.children.length; index++) {
  //         const posNode = pengziNode.children[index];
  //         console.log("清除操作posNode", posNode);

  //         // posNode["hasFlower"] = true;
  //         // posNode["flowerNode"] = null;
  //         // posNode["flowerNode"].destroy();
  //       }
  //     }
  //   }
  // }

  // update (dt) {}
}
